Well, the first day of my adventure has been relatively straightforward and, aided by a little cider brandy, I have finished the exercises.
The first of the seven new languages is Lua and the chapter covering it is written by Ian Dees. He compares Lua to Indiana Jones and tells a story of how Lua helped save a project he once worked on.
And then he cracks straight on to the language basics — tables, maths, using the REPL, and so on.
My experiences
I installed Lua on my Debian Jessie box with a simple aptitude install command like this.
$ sudo aptitude install lua5.2
Then I did some noodling about to get my Seven More Languages In Seven Weeks repository set up on gitorious. Programming is often about 70 percent setting up your environment, I suppose.
The exercises
Easy exercises
Write a function called ends_in_3(num) that returns true if the final digit of num is 3, and false otherwise
This was pretty easy though my implementation has a bug when dealing with larger numbers.
function ends_in_3(num)
l = string.len(tostring(num))
return string.sub(num,l,l) == "3"
end
The bug surfaces when Lua moves to representing numbers using scientific notation.
> return ends_in_3(2123323213213213213123)
false
Because
> =2123323213213213213123
2.1233232132132e+21
Meaning that the number "ends in" 1 not 3 as expected. An interesting bug, but not one I can be arsed to fix for this exercise.
Now, write a similar function called is_prime(num) to test if a number is prime (that is, it's divisible by itself and 1).
The secret here is to only check numbers up to n^(1/2), otherwise the implementation will be intolerably slow. There are better implementations, but this one is pretty reasonable for these purposes. HT to Project Euler for teaching me more about primes than I thought I wanted to know!
function is_prime (n)
for i=2, n^(1/2) do
if ( n % i == 0) then
return false
end
end
return true
end
Create a program to print the first n prime numbers that end in 3
I simply made a function to combine the previous two. Apologies for the dull but verbose name.
function first_n_primes_ending_in_3 (n)
primes = {}
i=0
while(#primes<n) do
i=i+1
if(is_prime(i) and ends_in_3(i)) then
primes[#primes+1]=i
end
end
return primes
end
Medium exercise
What if Lua didn’t have a for loop? Using if and while, write a function for_loop(a,b,f) that calls f() on each integer from a to b (inclusive).
I think I missed the point of this exercise as it seems so trivial and I can see no reason for requiring an if (error handline perhaps?)
function for_loop(a,b,f)
local i=a -- loop counter, create local var rather than reuse 'a'.
while(i <= b) do
f(i)
i=i+1
end
end
Hard exercises
Write a function reduce(max, init, f) that calls a function over the integers from 1 to max like so:
function add(previous, next) return previous + next end
I wasn’t entirely happy with my imperitive-feeling implementation. Still it does follow the same logic as that described in the spec.
function reduce(max, init, f)
local acc = init
for i=1, max do
acc = f(acc, i)
end
return acc
end
Implement factorial() in terms of reduce()
I went down the route of implementing a product function in terms of reduce first and then implementing factorial in terms of that.
function product(n,m)
return n * m
end
function fac(n)
return reduce(n, 1, product)
end